/*
 * element.c
 *
 *  Created on: Apr 20, 2011
 *      Author: mariano
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../include/element.h"

Element * newElement(char * name) {
	Element * out = malloc(sizeof(Element));
	out->name = malloc((strlen(name)+1) * sizeof(char));
	strcpy(out->name, name);
	return out;
}

void deleteElement(Element * e) {
	if (e != NULL)
		free(e->name);
	free(e);
}

Magic * newMagic(Element * e1, Element * e2, Element * output) {
	Magic * out = malloc(sizeof(Magic));
	out->e1 = e1;
	out->e2 = e2;
	out->output = output;
	return out;
}

int elementCmp(Element * e1, Element * e2) {
	return strcmp(e1->name, e2->name) == 0;
}

// Magic does not destroy elements...
void deleteMagic(Magic * m) {
	free(m);
}

void printElement(Element * e) {
	if (e != NULL)
		printf("%s\n", e->name);
	else
		printf("(null)\n");
}

void printMagicOutput(Magic *m){
	if (m != NULL && m->e1 != NULL && m->e2 != NULL && m->output != NULL)
		printf("%s\n",m->output->name);
}

void printMagic(Magic * m) {
	if (m != NULL && m->e1 != NULL && m->e2 != NULL && m->output != NULL)
		printf("[%s,%s] -> %s\n", m->e1->name, m->e2->name, m->output->name);
}

int isReactor(Magic * magic, Element * reactor) {
	return (elementCmp(magic->e1, reactor) || elementCmp(magic->e2, reactor));
}

int isProduct(Magic * magic, Element * reactor) {
	return elementCmp(magic->output, reactor);
}

Element * getMagicProduct(Magic * magic) {
	return magic->output;
}

Element * getMagicFirstReactor(Magic * magic) {
	return magic->e1;
}

Element * getMagicSecondReactor(Magic * magic) {
	return magic->e2;
}

int elementAlfabeticCmp(Element * e1, Element * e2) {
	return e2->name[0] - e1->name[0];
}

int isTerminal(Element * element, Array * magics) {
	int i;
	int flag = 0;
	for (i = 0; i < magics->count && !flag; i++) {
		flag = isReactor(getElementByIndex(magics, i), element);
	}
	return !flag;
}

int isBasic(Element * element, Array * magics) {
	int i;
	int flag = 0;
	for (i = 0; i < magics->count && !flag; i++) {
		flag = isProduct(getElementByIndex(magics, i), element);
	}
	return !flag;
}

bool pseudoMagicCmp(Magic *m1, Magic *m2) {
	if (m1 != NULL && m2 != NULL)
		return (elementCmp(m1->e1, m2->e1) && elementCmp(m1->e2, m2->e2)) || elementCmp(m1->e1, m2->e2) && elementCmp(m1->e2, m2->e1);
	return false;
}
